package com.tengju.bff.interfaces.shared;

import com.tengju.data.domain.model.analysis.Meta;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chenhang
 * @Date 2021/3/6
 */
@Data
@ApiModel(value = "ColumnVO", description = "表头对象")
public class ColumnVO {

    @ApiModelProperty(value = "定义")
    String prop;
    @ApiModelProperty(value = "描述")
    String label;
    @ApiModelProperty(value = "表格样式")
    ColumnAttrs attrs;
    @ApiModelProperty(value = "能否排序")
    boolean sortable;

    List<ColumnVO> children;

    Meta meta;

    Boolean root;

    Integer rowFrom;
    Integer rowTo;
    Integer colFrom;
    Integer colTo;

    private ColumnVO() {
    }

    private ColumnVO(String prop, String label, List<ColumnVO> children, Boolean root) {
        this.prop = prop;
        this.label = label;
        this.sortable = false;
        this.children = children;
        this.root = root;
    }

    private ColumnVO(String prop, String label, ColumnAttrs attrs, boolean sortable, List<ColumnVO> children) {
        this.prop = prop;
        this.label = label;
        this.attrs = attrs;
        this.sortable = sortable;
        this.children = children;
    }

    public static ColumnVO of(String prop, String label) {
        return new ColumnVO(prop, label, null, false, List.of());
    }

    public static ColumnVO of(String prop, String label, boolean sortable) {
        return new ColumnVO(prop, label, null, sortable, List.of());
    }

    public static ColumnVO of(String prop, String label, List<ColumnVO> children) {
        return new ColumnVO(prop, label, null, false, children);
    }

    public static ColumnVO of(String prop, String label, List<ColumnVO> children, Boolean root) {
        return new ColumnVO(prop, label, children, root);
    }

    public static ColumnVO of(String prop, String label, ColumnAttrs attrs, boolean sortable) {
        return new ColumnVO(prop, label, attrs, sortable, List.of());
    }

    public void setDepthList(List<Integer> depthList, int depth) {
        if (CollectionUtils.isEmpty(children)) {
            depthList.add(depth);
        } else {
            depth++;
            for (ColumnVO columnVO : children) {
                columnVO.setDepthList(depthList, depth);
            }
        }
    }

    public void setRoot(Boolean root) {
        this.root = root;
    }

    public int width() {
        int width = 0;
        if (CollectionUtils.isEmpty(children)) {
            width = 1;
        } else {
            for (ColumnVO columnVO : children) {
                width = width + columnVO.width();
            }
        }
        return width;
    }

    public void addChild(ColumnVO child) {
        if (CollectionUtils.isEmpty(children)) {
            children = new ArrayList<>();
        }
        children.add(child);
    }

    public Map<String, Integer> filledRowCol(int rowFrom, int colFrom, int maxDepth) {
        if (CollectionUtils.isEmpty(children)) {
            if (root != null && root) {
                this.rowFrom = rowFrom;
            } else {
                this.rowFrom = rowFrom + maxDepth - 1;
            }
            this.rowTo = rowFrom + maxDepth;
            this.colFrom = colFrom;
            this.colTo = colFrom + 1;
            Map<String, Integer> end = new HashMap<>();
            end.put("rowFrom", this.rowFrom);
            end.put("colEnd", this.colTo);
            return end;
        } else {
            int col = colFrom;
            Map<String, Integer> end = new HashMap<>();
            for (ColumnVO columnVO : children) {
                end = columnVO.filledRowCol(rowFrom, col, maxDepth);
                col = end.get("colEnd");
            }
            if (root != null && root) {
                this.rowFrom = rowFrom;
            } else {
                this.rowFrom = end.get("rowFrom") - 1;
            }
            this.rowTo = end.get("rowFrom");
            this.colFrom = colFrom;
            this.colTo = col;
            end.put("rowFrom", this.rowFrom);
            end.put("colEnd", this.colTo);
            return end;
        }
    }

    /**
     * 递归获取当前节点以及子节点
     *
     * @return 当前节点以及子节点的集合
     */
    public List<ColumnVO> allColumn() {
        List<ColumnVO> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(children)) {
            result.add(this);
            for (ColumnVO column : children) {
                result.addAll(column.allColumn());
            }
        } else {
            result.add(this);
        }
        return result;
    }

    /**
     * 递归获取所有的子节点
     *
     * @param result 子节点集合
     */
    public void setAllChildColumn(List<ColumnVO> result) {
        if (!CollectionUtils.isEmpty(children)) {
            for (ColumnVO column : children) {
                column.setAllChildColumn(result);
            }
        } else {
            result.add(this);
        }
    }
}
